
import { _decorator, Node, EventMouse, Vec2, UITransform, Vec3, EventTouch, EventHandler, Button, Sprite, PolygonCollider2D, Intersection2D, Label, tween, Tween } from 'cc';
import { DEV, EDITOR } from 'cc/env';
import { KeyCodeHandler } from './KeyCodeHandler';
import { SuperCheck } from './SuperCheck';
import { SuperCursor } from './SuperCursor';
import { NeighborHandler } from './NeighborHandler';
import { KeyBoardEvent } from '../KeyboardDefine';
import { InputKeyCode } from '../../core/InputConfig';
import GameInputEvent from '../../core/GameInputEvent';
import { engine } from '../../../engine/engine';
import GEvent from '../../../cfw/event/GEvent';
const { ccclass, property, requireComponent } = _decorator;

export const MOUSE_ENTER_TIME = 0.2;
export const MOUSE_LEAVE_TIME = 0.2;

/**
 * Predefined variables
 * Name = CursorView
 * DateTime = Thu Sep 16 2021 18:20:05 GMT+0800 (中国标准时间)
 * Author = moxiangyouxi
 * FileBasename = CursorView.ts
 * FileBasenameNoExtension = CursorView
 * URL = db://assets/scripts/app/mediator/common/CursorView.ts
 * ManualUrl = https://docs.cocos.com/creator/3.3/manual/zh/
 *
 */
// export enum CursorDirection {
//     up,
//     left,
//     down,
//     right,
// };
// Enum(CursorDirection);

const _tempVec3 = new Vec3();
// const _tempVec3_1 = new Vec3();
const _vec2a = new Vec2();
const _vec2b = new Vec2();
const _vec3a = new Vec3();
// const _mat4_temp = new Mat4();
// const _matrix = new Mat4();
// const _worldMatrix = new Mat4();
// const _zeroMatrix = new Mat4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// const _rect = new Rect();

export type CursorItemFunc = (node: Node, select: boolean) => void;
@ccclass('SuperButton')
@requireComponent([SuperCheck, SuperCursor, NeighborHandler])
export class SuperButton extends Button {
    // @property({ type: Enum(InputKeyCode) })
    keyCode: InputKeyCode = InputKeyCode.NONE;

    @property(Label)
    private _keyTipLabel: Label = null;
    @property(Label)
    get keyTipLabel() {
        if (!this._keyTipLabel) {
            let children = this.node.children;
            for (let i = 0; i < children.length; i++) {
                this._keyTipLabel = children[i].getComponent(Label);
                if (this._keyTipLabel) {
                    break;
                }
            }
            if (this._keyTipLabel) {
                let label = this._keyTipLabel.node.getComponent(Label);
                label.overflow = Label.Overflow.NONE;
            }
        }
        return this._keyTipLabel;
    }

    set keyTipLabel(label: Label) {
        this._keyTipLabel = label;
    }

    @property(Sprite)
    private _keyTipSprite: Sprite = null;
    @property(Sprite)
    get keyTipSprite() {
        if (!this._keyTipSprite) {
            this._keyTipSprite = this.node.getChildByName("KeyTip")?.getComponent(Sprite);
            if (this._keyTipSprite) {
                this._keyTipSprite.sizeMode = Sprite.SizeMode.TRIMMED;
            }
        }
        return this._keyTipSprite;
    }

    set keyTipSprite(sprite: Sprite) {
        this._keyTipSprite = sprite;
    }

    @property({ tooltip: DEV && "键盘移动仅选中不发点击事件" })
    @property
    kbOnlyCheck: boolean = true;


    @property({ tooltip: DEV && "当鼠标悬停时是否自动选中" })
    @property
    autoCheckOnHover: boolean = false;

    // @property({ tooltip: DEV && "是否监听键盘的抬起和鼠标的按下事件" })
    // @property
    // hasUpEvent: boolean = false;

    @property({ tooltip: DEV && "离开按钮需要设置的功能Feature表id,默认为0 不触发。" })
    @property
    featureId: number = 0;

    @property({ tooltip: DEV && "是否监听键盘的抬起和鼠标的按下事件" })
    @property
    isFeatureExit: boolean = false;




    protected collider: PolygonCollider2D;

    sHoverCallback: Function = null;//处于列表中的悬停回调
    sSelectedCallback: Function = null;//处于列表中的选择回调

    private _kcHandler: KeyCodeHandler = null;
    private _isKeyboardLayoutItem: boolean = false;//是否是KeyboardLayout子项

    public set isKeyboardLayoutItem(value: boolean) {
        this._isKeyboardLayoutItem = value;
    }

    public get kcHandler() {
        if (!this._kcHandler) {
            this._kcHandler = this.node.addComponent(KeyCodeHandler);
            this._kcHandler.handler.target = this.node;
            this._kcHandler.handler.component = "SuperButton";
            this._kcHandler.handler.handler = "onKeyBoardPress";
            // this._kcHandler.hasUpEvent = this.hasUpEvent;
            // this._kcHandler.isActive = !this._isKeyboardLayoutItem;
        }
        return this._kcHandler;
    }

    protected _check: SuperCheck;
    get check(): SuperCheck {
        if (!this._check) {
            this._check = this.node.getComponent(SuperCheck)
            if (!this._check) {
                this._check = this.node.addComponent(SuperCheck)
            }
        }
        return this._check;
    }
    protected _cursor: SuperCursor;
    get cursor(): SuperCursor {
        if (!this._cursor) {
            this._cursor = this.node.getComponent(SuperCursor)
            if (!this._cursor) {
                this._cursor = this.node.addComponent(SuperCursor)
            }
        }
        return this._cursor;
    }

    private _isHover: boolean = false;

    public get isHover() {
        return this._isHover;
    }




    private _isMouseDown: boolean = false;
    private _isMouseDownLast: boolean = false;

    start() {
        if (EDITOR) {
            return;
        }

        this.node.on(Node.EventType.MOUSE_ENTER, (event: EventMouse) => {
            // console.log("MOUSE_ENTER -", this.node.name);
            if (!this.interactable) {
                return;
            }
            if (this.autoCheckOnHover) {
                this.onSelected();
            } else {
                this.onFocusEvent();
            }
            this._isMouseDown = this._isMouseDownLast;
        }, this);

        this.node.on(Node.EventType.MOUSE_MOVE, (event: EventMouse) => {
            // console.log("MOUSE_ENTER -", this.node.name);
            //TODO 123光标移动检测悬停
            // this.onFocusEvent();
        }, this);

        this.node.on(Node.EventType.MOUSE_LEAVE, (event: EventMouse) => {
            // console.log("MOUSE_LEAVE -", this.node.name);
            if (!this.interactable) {
                return;
            }
            if (this.autoCheckOnHover) {
                this.onUnSelected();
            } else {
                this.onBlurEvent();
            }
            this._isMouseDownLast = this._isMouseDown;
        }, this);





        let buttons = this.getComponents(Button);
        if (buttons.length > 1) {
            engine.error("不能挂载多个Button", this.node.name);
            for (let i = 0; i < buttons.length; i++) {
                if (!(buttons[i] instanceof SuperButton)) {
                    engine.error("禁用多余的Button", this.node.name);
                    buttons[i].enabled = false;
                }
            }
        }



        this.collider = this.node.getComponent(PolygonCollider2D)
        if (this.collider) {
            let uiTransform = this.node.getComponent(UITransform)
            uiTransform.hitTest = this.hitTest.bind(this)
        }
    }
    public hitTest(screenPoint: Vec2) {
        console.log(' hitTest ')
        const v3WorldPt = _vec3a;
        const v2WorldPt = _vec2a;
        const testPt = _vec2b;

        const cameras = this._getRenderScene().cameras;
        for (let i = 0; i < cameras.length; i++) {
            const camera = cameras[i];
            if (!(camera.visibility & this.node.layer)) continue;

            // Convert Screen Space into World Space.
            Vec3.set(v3WorldPt, screenPoint.x, screenPoint.y, 0);  // vec3 screen pos
            camera.screenToWorld(v3WorldPt, v3WorldPt);
            Vec2.set(v2WorldPt, v3WorldPt.x, v3WorldPt.y);

            let hit = false;
            hit = Intersection2D.pointInPolygon(v2WorldPt, this.collider.worldPoints)
            if (hit) {
                return true;
            }
        }
        return false;
    }
    onEnable() {
        super.onEnable()
        // CursorController.instance().onBlurEvent(this);
    }

    onDisable() {
        super.onDisable()
        // CursorController.instance().onBlurEvent(this);
    }
    //是否拦截事件
    private isInterceptInput() {
        if (this.featureId) {
            let intercept = {
                result: false,
                isFeatureExit: this.isFeatureExit,
                featureId: this.featureId
            }
            GEvent.instance().emit(KeyBoardEvent.LeaveUI, intercept)
            // Facade.getInstance().sendNotification(CommandDefine.LeaveUI, intercept)
            engine.log(' intercept.result ', intercept.result)
            return intercept.result;
            // return false;
        } else {
            return false;
        }
    }
    private isScaling: boolean = false;
    private tween: Tween<any> = null;
    onKeyBoardPress(event?: GameInputEvent) {
        if (!this.interactable || !this.node.parent) {
            return;
        }

        if (this.isScaling) {
            return;
        }

        if (this.isInterceptInput()) {
            return;
        }
        if (event) {
            event.target = this.node;
        }
        this.onSelected();
        EventHandler.emitEvents(this.clickEvents, event);
        // this.playSound();
        if (event.isKeyboard) {
            // this.isScaling = true;
            this._zoomUp();
            if (this.tween) {
                this.tween.stop()
                this.tween = null;
            }
            this.tween = tween(this.node).delay(0.2).call(() => {
                // this.isScaling = false;

                this._zoomBack();
            }).start()
        } else {
            // this.onSelected();
            // EventHandler.emitEvents(this.clickEvents, event);
        }
    }

    // protected _onTouchBegan(event?: EventTouch) {
    //     if (!this._interactable || !this.enabledInHierarchy) {
    //         return;
    //     }
    //     // if (this.mouseEvents.length > 0) {
    //     //     return;
    //     // }
    //     super._onTouchBegan(event);
    //     if (this.hasUpEvent) {
    //         EventHandler.emitEvents(this.clickEvents, event)
    //     }
    // }
    protected _onTouchCancel(event?: EventTouch) {
        if (!this._interactable || !this.enabledInHierarchy) {
            return;
        }
        // if (this.mouseEvents.length > 0) {
        //     return;
        // }
        super._onTouchCancel(event);
        // if (this.hasUpEvent) {
        //     event.type = Node.EventType.TOUCH_END
        //     EventHandler.emitEvents(this.clickEvents, event)
        // }
    }
    protected _onTouchEnded(event?: EventTouch) {
        if (!this._interactable || !this.enabledInHierarchy) {
            return;
        }
        // if (this.mouseEvents.length > 0) {
        //     return;
        // }
        if (this.isInterceptInput()) {
            return;
        }
        this.onSelected(event);
        super._onTouchEnded(event);
        this.playSound();
    }

    kbSoundEventId: number = 10106;//设置默认音效

    private playSound() {
        if (this.kcHandler.soundEventId) {
            this.kcHandler.sound();
        } else if (this.kbSoundEventId) {
            GEvent.instance().emit(KeyBoardEvent.PLAY_AUDIO, this.kbSoundEventId)
        }
    }




    public setKeyCode(keyCode: InputKeyCode) {
        this.keyCode = keyCode;
        this.kcHandler.keyCode = this.keyCode;
        // this.setKeyTipSprite();
    }




    public getCursorWorldPosition(): Vec3 {
        this.cursor.getCursorPosition();
        return Vec3.add(_tempVec3, this.node.worldPosition, _tempVec3);
    }

    isFocused() {
        // let cursorView = CursorController.instance().cursorView;
        // return cursorView && cursorView.node && cursorView.node.parent == this.node;
        return false;
    }

    setHoverState(hover: boolean) {
        this._isHover = hover;
        // if (this._hoverCallback) {
        //     this._hoverCallback(this.node, hover);
        // }
        EventHandler.emitEvents(this.cursor.hoverEvents, this);
    }

    setSelectedState(select: boolean) {
        this.check.isChecked = select;
        // if (this._selectedCallback) {
        //     this._selectedCallback(this.node, select);
        // }
        if (select) {
            this.onFocusEvent();
        } else {
            this.onBlurEvent();
        }
        EventHandler.emitEvents(this.check.checkEvents, this);
    }

    public onFocusEvent() {
        // CursorController.instance().onFocusEvent(this);
        this.onHover();
    }

    public onBlurEvent() {
        // CursorController.instance().onBlurEvent(this);
        this.onUnHover();
    }

    public onHover() {
        if (this.sHoverCallback) {
            this.sHoverCallback(this, true);
        } else {
            this.setHoverState(true);
        }
    }

    public onUnHover() {
        if (this.sHoverCallback) {
            this.sHoverCallback(this, false);
        } else {
            this.setHoverState(false);
        }
    }

    public onSelected(event?: EventTouch) {
        if (this.sSelectedCallback) {
            this.sSelectedCallback(this, true, event);
        } else {
            this.setSelectedState(true);
        }
    }

    public onUnSelected() {
        if (this.sSelectedCallback) {
            this.sSelectedCallback(this, false);
        } else {
            this.setSelectedState(false);
        }
    }

    /**
     * 点击事件（从容器中触发的，根据kbOnlyCheck不同处理）
     * @returns 
     */
    public onClickForContainer() {
        if (!this.interactable) {
            return;
        }
        if (this.kbOnlyCheck) {
            this.onSelected();
        } else {
            this.onClick();
        }
    }

    /**
     * 点击事件（当主动响应按钮click事件时调用）
     */
    public onClick(playSound: boolean = false) {
        let event = new GameInputEvent();
        event.isKeyboard = false;
        this.onKeyBoardPress(event);
        if (playSound) {
            this.playSound();
        }
    }
}
